/* Copyright (c) 2021, National University of Defense Technology. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "par_vector.h"

namespace YHAMG
{

Par_Vector::Par_Vector()
	: comm(MPI_COMM_SELF)
{
}

Par_Vector::Par_Vector(MPI_Comm _comm)
	: comm(_comm)
{
}


Par_Vector::Par_Vector(MPI_Comm _comm, int Loc_size, double* Loc_values, int Loc_ref)
	: comm(_comm),
	Loc(Loc_size, Loc_values, Loc_ref)
{
}

Par_Vector::Par_Vector(const Par_Vector& x)
	: comm(x.comm),
	Loc(x.Loc)
{
}

Par_Vector::Par_Vector(Par_Vector&& x)
	: comm(x.comm),
	Loc(x.Loc.size, x.Loc.values, x.Loc.ref)
{
	x.Loc.ref = 1;
}

Par_Vector& Par_Vector::operator=(double a)
{
	Loc = a;
	return *this;
}

Par_Vector& Par_Vector::operator=(const Par_Vector& x)
{
	comm = x.comm;
	Loc = x.Loc;
	return *this;
}

Par_Vector& Par_Vector::operator=(Par_Vector&& x)
{
	Free();

	comm = x.comm;
	Loc.ref = x.Loc.ref;
	Loc.size = x.Loc.size;
	Loc.values = x.Loc.values;

	x.Loc.ref = 1;

	return *this;
}

void Par_Vector::Free()
{
	Loc.Free();
}

void Par_Vector::Resize(int n)
{
	Loc.Resize(n);
}

void Par_Vector::Reference(const Par_Vector& x)
{
	comm = x.comm;
	Loc.Reference(x.Loc);
}

void Par_Vector::Fill(double a) const
{
	Loc.Fill(a);
}

void Par_Vector::FillRandom() const
{
	Loc.FillRandom();
}

void Par_Vector::Copy(const Par_Vector& x) const
{
	Loc.Copy(x.Loc);
}

void Par_Vector::Scale(double a) const
{
	Loc.Scale(a);
}

void Par_Vector::Shift(double a) const
{
	Loc.Shift(a);
}

void Par_Vector::AddScaled(double a, const Par_Vector& x) const
{
	Loc.AddScaled(a, x.Loc);
}

void Par_Vector::Add2Scaled(double a, const Par_Vector& x, double b, const Par_Vector& y) const
{
	Loc.Add2Scaled(a, x.Loc, b, y.Loc);
}

}